package sjcc

import (
	"errors"
	"os"
	"os/exec"
	"path/filepath"
	"strings"
)

type SJcmd struct {
	cpu  string
	tar  string
	args []string
	srcs []string
}

func NewLink(cpu string, srcs []string, tar string) (*SJcmd, error) {
	return &SJcmd{cpu: cpu, srcs: srcs, tar: tar, args: []string{}}, nil
}

func (cmd *SJcmd) AddArgs(arg []string) {
	cmd.args = append(cmd.args, arg...)
}

func (cmd *SJcmd) CreateExec() (*exec.Cmd, error) {

	/**/
	if len(cmd.tar) <= 0 {
		return nil, errors.New("link target null")
	}

	/**/
	if len(cmd.srcs) <= 0 {
		return nil, errors.New("link srcs null")
	}

	/**/
	exx := exec.Command(blink, "-o", cmd.tar)

	/* xxx.ind */
	indfn := strings.TrimSuffix(cmd.tar, filepath.Ext(cmd.tar)) + ".ind"
	fp, err := os.Create(indfn)
	if err != nil {
		return nil, errors.New("ind file create fail")
	}
	defer fp.Close()

	/**/
	if cmd.cpu == "cortex-A5" {
		/**/
		maddArgs(exx, "-m armelf")
		maddArgs(exx, "--fatal-warnings --gc-sections")

		/**/
		for _, v := range cmd.srcs {
			fp.WriteString("\"" + v + "\"\n")
		}

		libc := filepath.Join(blib, "libc_v7a_le.a")
		fp.WriteString("\"" + libc + "\"\n")

		libm := filepath.Join(blib, "libm_v7a_le.a")
		fp.WriteString("\"" + libm + "\"\n")
	
	} else if cmd.cpu == "cortex-M0" {

		maddArgs(exx, "-m armelf")
		maddArgs(exx, "--fatal-warnings --gc-sections")

		/**/
		for _, v := range cmd.srcs {
			fp.WriteString("\"" + v + "\"\n")
		}
		
		libc := filepath.Join(blib, "libc_v6m_t_le_eabi_ienum.a")
		fp.WriteString("\"" + libc + "\"\n")

		libm := filepath.Join(blib, "libm_v6m_t_le_eabi_ienum.a")
		fp.WriteString("\"" + libm + "\"\n")

	} else if cmd.cpu == "risv32" {

		crt0 := filepath.Join(blib, "riscv_crt0.s.o")
		fp.WriteString("\"" + crt0 + "\"\n")

		/**/
		for _, v := range cmd.srcs {
			fp.WriteString("\"" + v + "\"\n")
		}

		libc := filepath.Join(blib, "libc_rv32ima_small.a")
		fp.WriteString("\"" + libc + "\"\n")

		libm := filepath.Join(blib, "libm_rv32ima_small.a")
		fp.WriteString("\"" + libm + "\"\n")

		libgs := filepath.Join(blib, "libgloss.a")
		fp.WriteString("\"" + libgs + "\"\n")

		maddArgs(exx, "-Ttext 0x1000000")
		maddArgs(exx, "-Tdata 0x8000000")

	} else {
		return nil, errors.New("not support the cpu")
	}

	/**/
	for _, v := range cmd.args {
		maddArgs(exx, v)
	}

	exx.Args = append(exx.Args, "--start-group", "@"+indfn, "--end-group")
	return exx, nil
}
